/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.txt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.List;
import java.util.StringTokenizer;

import lineage.util.PerformanceTimer;
import lineage.util.StreamUtil;
import lineage.util.Util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 从本地加载(.txt)文件内容的抽象类.
 * 
 * @version 2014年3月15日下午3:25:38
 * @author jrwz
 */
public abstract class L1AbstractTXT {
    private static final Logger LOG = LoggerFactory.getLogger(L1AbstractTXT.class);
    /** List接口所实现的列表. */
    protected List<String> list;

    /**
     * 取得要加载文件的相对路径.
     * 
     * @return 文件的相对路径(包括文件的完整名称)
     */
    protected abstract String getURL();

    /**
     * 取得要显示的提示信息.
     * 
     * @return 提示信息
     */
    protected abstract String getMsg();

    /**
     * 取得List接口所实现的列表.
     * 
     * @return List接口的大小可变数组的实现 比如ArrayList
     */
    protected abstract List<String> getListAchieve();

    /**
     * 初始化.
     * 从本地(.txt)文件内逐行读取全部内容至(List列表内),如果之前该列表内有内容则清空再加入.
     */
    protected L1AbstractTXT() {
        getURL();
        list = getListAchieve();
        load();
    }

    /**
     * 从本地(.txt)文件内逐行读取全部内容至(List列表内).
     */
    private void load() {
        final PerformanceTimer timer = new PerformanceTimer();
        StringBuilder sb = new StringBuilder();
        sb.append("\r\n--------------------------------------------\r\n");
        sb.append(getMsg());
        LineNumberReader lnr = null;
        try {
            final File file = new File(getURL());
            final FileInputStream fileIn = new FileInputStream(file);
            final InputStreamReader inputStream = new InputStreamReader(fileIn, "utf8");
            lnr = new LineNumberReader(inputStream);

            boolean isWhile = false;
            String line = null;
            while ((line = lnr.readLine()) != null) {
                if (!isWhile) { // 忽略第一行
                    isWhile = true;
                    continue;
                }
                if ((line.trim().length() == 0) || line.startsWith("#")) {
                    continue;
                }
                final StringTokenizer st = new StringTokenizer(line, "\r\n");
                final String info = st.nextToken();
                list.add(info);
            }
        } catch (final FileNotFoundException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } catch (final Exception e) {
            LOG.error(e.getLocalizedMessage(), e);
        } finally {
            StreamUtil.close(lnr);
            sb.append("(");
            sb.append(list.size());
            sb.append(")\t耗时 ");
            sb.append(timer.elapsedTimeMillis());
            sb.append(" 毫秒");
            sb.append("\r\n--------------------------------------------\r\n");
            Util.message(Util.SYSTEM_MESSAGE, sb.toString());
        }
    }

    /**
     * 取得内容.
     * 
     * @return 列表内的所有内容
     */
    public String getMessage() {
        final StringBuilder sb = new StringBuilder();
        for (final String str : list) {
            sb.append(str + "\n");
        }
        return sb.toString();
    }

    /**
     * 重置(清空之前列表的内容并重新加载本地文件内容至列表内).
     */
    public void reset() {
        if (!list.isEmpty()) {
            list.clear(); // 移除此列表中的所有元素
        }
        load();
    }

    /**
     * 取得列表.
     * 
     * @return 列表
     */
    public List<String> getList() {
        return list;
    }
}
